// 
//  SimpleLanguage.cs
//  
//  Author:
//       Daniel Großer <olav.daniel.grosser@googlemail.com>
//  
//  Copyright (c) 2012 Copyright (C) 2012 by Daniel Großer. This Code is under GNU LGPL 3.0
// 
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
// 
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU Lesser General Public License for more details.
// 
//  You should have received a copy of the GNU Lesser General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using Beauty;
using Beauty.Tools;

namespace Beauty.Test.Languages.SimpleLanguage
{
	public class Block : ASTNode
	{
	   [Production(IsOptional=true)]
	   public VariablePart Declaration { get; set; }
	
	   [Keyword("begin")]
	   public string Begin { get; set; }
	
	   [Production]
	   public ICollection<Statement> Statements { get; set; }
	
	   [Keyword("end")]
	   public string End { get; set; }   
	}
	
	public class VariablePart : ASTNode
	{
	   [Keyword("var")]
	   public string Var { get; set; }
	
	   [Production]
	   public VariableDeclaration[] Declarations { get; set; }
	}
	
	public class VariableDeclaration : ASTNode
	{
	   [Production]
	   public Identifier Name { get; set; }
	
	   [Delimeter(":")]
	   public char Colon { get; set; }
	
	   [Production]
	   public PredefinedType Type { get; set; }
	
	   [Delimeter(";")]
	   public char Semicolon { get; set; }
	}
	
	public class Identifier : ASTNode
	{
	   [RegExTerminal("[A-Za-z][A-Za-z0-9]*")]
	   public string Name { get; set; }
	}
	
	public abstract class PredefinedType : ASTNode
	{
	}
	
	public class StringType : PredefinedType
	{
	   [Keyword("string")]
	   public string TypeName { get; set; }
	}
	
	public class IntType : PredefinedType
	{
	   [Keyword("int")]
	   public string TypeName { get; set; }
	}
	
	public class Statement : ASTNode
	{
	   [Production]
	   public Identifier VariableOrMethod { get; set; }
	
	   [Production(IsOptional=true)]
	   public StatementRest Rest { get; set; }
	
	   [Delimeter(";")]
	   public char Semicolon { get; set; }
	}
	
	public class StatementRest : ASTNode
	{
	   [Delimeter(":=")]
	   public object Assign { get; set; }
	
	   [Production]
	   public BinaryExpression LeftHandSide { get; set; }
	}
	
	public class BinaryExpression : ASTNode
	{
	   [Production]
	   public SimpleExpression FirstOperand { get; set; }
	
	   [RegExTerminal(@"[\+\-\/\*]", IsOptional = true)]
	   public char Operand { get; set; }
	
	   [Production(DependsOn = "Operand")]
	   public SimpleExpression SecondOperand { get; set; }
	}
	
	public abstract class SimpleExpression : ASTNode
	{
	}
	
	public class IdentifierExpression : SimpleExpression
	{
	   [Production]
	   public Identifier Name { get; set; }
	}
	
	public class NumericLiteral : SimpleExpression
	{
	   [RegExTerminal("[0-9]+")]
	   public int Value { get; set; }
	}	
}

